from google.colab import files
uploaded = files.upload() # 파일 업로드 기능 실행
for fn in uploaded.keys(): # 업로드된 파일 정보 출력
print('User uploaded file "{name}" with length {length} bytes'.format(
name=fn, length=len(uploaded[fn])))
from IPython.display import Image
Image("지도비지도.png")
분류는 다양한 머신러닝 알고리즘으로 구현할 수 있다.
● 베이즈 통계와 생성모델에 기반한 나이브 베이즈(Naive Bayse)
● 독립변수와 종속변수의 선형 관계성에 기반한 로지스틱 회귀(Logistic Regression)
● 데이터 균일도에 따른 규칙 기반의 결정트리(Decision Tree)
● 개별 클래스 간의 최대 분류 마진을 효과적으로 찾아주는 서포트벡터머신(SVM)
● 근접 거리를 기준으로 하는 최소 근접(Nearest Neighbor)
● 심층 연결 기반의 신경망(Neural Network)
● 서로 다른(또는 같은) 머신러닝 알고리즘을 결합한 앙상블(Ensemble)
from google.colab import files
uploaded = files.upload() # 파일 업로드 기능 실행
for fn in uploaded.keys(): # 업로드된 파일 정보 출력
print('User uploaded file "{name}" with length {length} bytes'.format(
name=fn, length=len(uploaded[fn])))
Image("결정트리.png")
많은 규칙이 있다는 것은 곧 분류를 결정하는 방식이 더욱 복잡해진다는 얘기이고, 이는 곧 과적합으로 이어지기 쉽다. 즉, 트리의 깊이(depth)가 깊어질수록 결정 트리의 예측 성능이 저하될 가능성이 높다.
가능한 한 적은 결정노드로 높은 예측 정확도를 가지려면 분류할 때 최대한 많은 데이터 세트가 해당 분류에 속할 수 있도록 결정노드의 규칙이 정해져야 한다.
결국은 트리를 어떻게 분할할 것인가가 중요함. 이를 위해서는 최대한 균일한 데이터 세트를 구성해야함.
조건을 걸을 때 결국 균일도가 높은 순으로 걸어주면 됨. why? 예측이 쉬우니깐!
장점 : 균일도라는 룰을 기반으로 하여 알고리즘이 쉬움. 특별한 경우를 제외하고는 각 변수의 스케일링과 정규화 같은 전처리 작업이 불필요.
단점 : 과적합으로 정확도가 떨어짐. 피처가 많고 균일도가 다양하게 존재할수록 트리의 깊이가 깊어지고 결국은 복잡하게 되어 과적합의 위험성이 있음.
단점 해결방안 : 트리의 크기를 사전에 제한하는 튜닝 필요.
DceisionTreeClassifier이랑 DceisionTreeRegressor이 있음.
우리는 분류문제만 다루기 때문에 DceisionTreeClassifier에 대해 배워볼 것임.
파라미터 종류로는 다음과 같음.
(트리의 깊이나 잎 노드 수가 일정 수에 도달하면 트리의 성장을 멈춤)
● min_samples_split
노드를 분할하기 위한 최소한의 샘플 데이터 수.
디폴트는 2
int일 경우 주어진 값을 그대로 사용, float일 경우 0에서 1사이의 값을 줄 수 있으며 전체 데이터 수*min_sample_split의 값을 사용.
클수록 과대적합 가능성 감소 / 작을수록 정확하나 과대적합 가능성 증가
● min_samples_leaf
노드가 되려면 가지고 있어야할 최소 샘플 수
클수록 과대적합 가능성 감소 / 작을수록 정확하나 과대적합 가능성 증가
단, 특정클래스의 데이터가 극도로 작을 수 있으므로 작게할 필요가 있음.
● max_features
최적의 분할을 위해 고려할 최대 features 개수
클수록 정확하나 과대적합 가능성 증가 / 작을수록 과대적합 가능성 감소
● max_depth
트리의 최대 깊이. 얼마나 깊게 트리를 만들어 갈거냐.
None 이면 최대한 깊게가면서 분할.
노드가 가지는 데이터 개수가 min_samples_split보다 작아질 때까지 계속 깊이를 증가시킴.
클수록 정확하나 과대적합 가능성 증가 / 작을수록 과대적합 가능성 감소
● max_leaf_nodes
밑단 노드의 최대개수
최대 몇개 잎 노드가 만들어 질때 까지 split(하위 (잎) 노드로 분리) 할 것이냐.
클수록 정확하나 과대적합 가능성 증가 / 작을수록 과대적합 가능성 감소
더 이상 자식이 없는 노드는 리프 노드이다. 즉, 최종 클래스(레이블)값이 결정되는 노드이다. 라프노드가 되기 위해서는 하나의 클래스 값으로 최종 데이터가 구성되거나 리프 노드가 될 수 있는 하이퍼 파라미터 조건을 충족하면 된다.
from google.colab import files
uploaded = files.upload() # 파일 업로드 기능 실행
for fn in uploaded.keys(): # 업로드된 파일 정보 출력
print('User uploaded file "{name}" with length {length} bytes'.format(
name=fn, length=len(uploaded[fn])))
Image("결정트리_시각화.png")
지니 계수의 값이 0이 되면 분류가 완료 된 것이고, 더이상 노드를 만들 필요가 없어진다.
class = setosa이면 하위 노드가 생겨날 경우 setosa로 분류되는게 제일 많다는 소리임.
value는 setosa, versicolor, virginica 순서임.
이러한 규칙으로 계속 진행되는 것임! 이 정도만 알고 넘겨도 OK.
from google.colab import files
uploaded = files.upload() # 파일 업로드 기능 실행
for fn in uploaded.keys(): # 업로드된 파일 정보 출력
print('User uploaded file "{name}" with length {length} bytes'.format(
name=fn, length=len(uploaded[fn])))
Image("깊이.png")
Image("split.png")
Image("leaf.png")
앙상블 학습을 통한 분류는 여러 개의 분류기를 생성하고 그 예측을 결합함으로써 보다 정확한 최종예측을 도출하는 기법임.
보팅(Voting) - 같은 데이터 샘플링 -> 서로 다른 알고리즘 분류기 적용
배깅(Bagging) - 다른 데이터 샘플링 -> 같은 알고리즘 분류기 적용(ex 랜덤포레스트) 부트스트래핑 분할 방식 사용
부스팅(Boosting) - 여러개의 알고리즘 분류기가 순차적으로 학습을 수행하되, 앞에서 학습한 분류기가 예측이 틀린 데이터에 대해서는 올바르게 예측할 수 있도록 가중치를 부여하면서 학습과 예측을 진행. (ex XGboost, LightGBM)
from google.colab import files
uploaded = files.upload() # 파일 업로드 기능 실행
for fn in uploaded.keys(): # 업로드된 파일 정보 출력
print('User uploaded file "{name}" with length {length} bytes'.format(
name=fn, length=len(uploaded[fn])))
from IPython.display import Image
Image("보팅배깅.jpg")
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
하드보팅 - 다수결원칙과 비슷. 예측한 결과값들 중 다수의 분류기가 결정한 예측값을 최종 보팅 결과값으로 선정.
소프트보팅 - 분류기들의 레이블 값 결정확률을 모두 더하고 이를 평균해서 이들 중 확률이 가장 높은 레이블 값을 최종 보팅 결과값으로 선정.
일반적으로 소프트보팅이 예측성능이 더 좋다고함.
from google.colab import files
uploaded = files.upload() # 파일 업로드 기능 실행
for fn in uploaded.keys(): # 업로드된 파일 정보 출력
print('User uploaded file "{name}" with length {length} bytes'.format(
name=fn, length=len(uploaded[fn])))
from IPython.display import Image
Image("소프트하드.jpg")
import pandas as pd
from sklearn.ensemble import VotingClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import KNeighborsClassifier
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
cancer = load_breast_cancer()
data_df = pd.DataFrame(cancer.data, columns=cancer.feature_names)
data_df.head(3)
# 개별 모델은 로지스틱 회귀와 KNN 임.
lr_clf = LogisticRegression()
knn_clf = KNeighborsClassifier(n_neighbors=8)
# 개별 모델을 소프트 보팅 기반의 앙상블 모델로 구현한 분류기
vo_clf = VotingClassifier( estimators=[('LR',lr_clf),('KNN',knn_clf)] , voting='soft' )
X_train, X_test, y_train, y_test = train_test_split(cancer.data, cancer.target,
test_size=0.2 , random_state= 156)
# VotingClassifier 학습/예측/평가.
vo_clf.fit(X_train , y_train)
pred = vo_clf.predict(X_test)
print('Voting 분류기 정확도: {0:.4f}'.format(accuracy_score(y_test , pred)))
# 개별 모델의 학습/예측/평가.
classifiers = [lr_clf, knn_clf]
for classifier in classifiers:
classifier.fit(X_train , y_train)
pred = classifier.predict(X_test)
class_name= classifier.__class__.__name__
print('{0} 정확도: {1:.4f}'.format(class_name, accuracy_score(y_test , pred)))
배깅의 대표적인 알고리즘임.
앙상블 알고리즘 중 비교적 빠른 수행 속도를 가지고 있음.
결정 트리 알고리즘을 기반으로 하여 쉽고 직관적인 장점을 그대로 가지고 있음.
여러개의 결정 트리 분류기가 전체 데이터에서 배깅 방식으로 각자의 데이터를 샘플링해 개별적으로 학습을 수행한 뒤 최종적으로 모든 분류기가 보팅을 통해 예측 결정을 하게 됨.
부트스트래핑 분할 방식을 따름. (중첩이 있도록 샘플링되게 분리하는 것)
from google.colab import files
uploaded = files.upload() # 파일 업로드 기능 실행
for fn in uploaded.keys(): # 업로드된 파일 정보 출력
print('User uploaded file "{name}" with length {length} bytes'.format(
name=fn, length=len(uploaded[fn])))
from IPython.display import Image
Image("부트.jpg")
from IPython.display import Image
Image("랜포.jpg")
트리 기반의 앙상블 알고리즘의 단점 - 너무 많은 하이퍼 파라미터와 튜닝 후에도 예측 성능 개선이 약하다는 것.
그나마 랜덤포레스트가 적은 편에 속함. Why? 결정트리에서 사용되는 하이퍼 파라미터와 같은 파라미터가 대부분이기 때문.
n_estimators : 랜덤포레스트에서 결정 트리의 개수를 지정. 디폴트 10
max_features : 결정트리에 사용된 max_features 파라미터와 같음.(최적의 분할을 위한 최대 feature의 개수) 결정트리에서는 기본적으로 None인데, 여기서는 auto(sqrt)임.
(ex) 16개 변수면 분할을 위해 4개 변수를 참조하겠다는 소리임.
부스팅 알고리즘은 여러개의 약한 학습기를 순차적으로 학습-예측하면서 잘못 예측한 데이터에 가중치 부여를 통해 오류를 개선하는 방식임.
대표적으로 에이다부스트(AdaBoost)와 그래디언트 부스트가 있음.
아래 그림은 에이다부스트에 대한 설명임.
from IPython.display import Image
Image("에이다.jpg")
그래디언트 부스트는 에이다부스트랑 원리는 같으나 가중치부여 방식이 다름.
아래와 같은 경사하강법을 통해 가중치를 부여해나감.
from IPython.display import Image
Image("경사하강.png")
loss: 경사 하강법에서 사용할 비용 함수를 지정, 특별한 이유가 없으면 기본값인 'deviance'를 지정
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
learning_rate: GBM이 학습을 진행할 때마다 적용하는 학습률이다. 약한 분류기가 순차적으로 오류 값을 보정해나가는데 적용하는 계수. (0~1사이의 값으로 디폴트는 0.1)
-> 매우 작게 설정: 업데이트되는 값이 작아져서 최소 오류 값을 찾아, 예측 성능이 높아질 가능성이 높음.
but 수행시간이 오래 걸리고, 너무 작게 설정하면, 최소 오류 값으 찾지 못할 수 도 있음.
-> 너무 크게 설정: 최소 오류값을 찾지 못하고 그냥 지나칠 확률이 높지만, 빠른 수행이 가능
=> n_estimators와 상호 보완적으로 조합해 사용해야 함. learning_rate를 작게하고 n_estimator를 크게하면됨. 하지만 너무 오래 걸리고, 예측 성향이 그렇게 좋아지는 것은 아님. 디폴트는 100
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
n_estimators: 약한 학습기의 개수. 순차적으로 오류를 정하므로, 개수가 많을 수록 예측 성향이 높아짐. 하지만, 수행시간이 오래 걸림.
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
subsample: 약한 학습기가 학습에 사용하는 데이터의 샘플링 비율임. 디폴트는 1아고 과적합을 방지하기 위해서는 1보다 작은 수를 사용.
from IPython.display import Image
Image("gbm.png")
-> XGboost도 max_depth로 방지가능하지만, 나무가지치기로 더 이상 긍정이득이 없는 분할을 가지치기해서 분할 수를 더 줄이는 추가적인 장점 있음.
ex). 조기 중단 파라미터 값을 50으로 설정하면, 50회 반복하는 동안, 오류가 감소하지 않으면 50에서 멈춤. -> 50이 최적이라는 것.
from IPython.display import Image
Image("가지치기.png")
주요 일반 파라미터
-booster: gbtree(tree based model)혹은 gblinear(linear model)선택
-silent(default= 0): 출력 메시지를 나타내고 싶지 않을 경우 1로 설정
-nthread(default= CPU의 전체 스레드 사용): CPU의 실행 스레드 개수를 지정
주요 부스터 파라미터: 트리 최적화, 부스팅 등과 관련 파라미터
-eta(default = 0.3, alias: learning_rate): 0과 1 사이의 값을 지정하며, 부스팅 스텝을 반복적으로 수행할 때 업데이트되는 학습률 값. cf. GBM의 learning rate와 같은 값. 사이키럿 래퍼 클래스 이용 시, learning_rate와 같은 값(default는 0.1)
-num_boost_rounds: 약한 분류기의 개수. 순차적으로 오류를 조정하므로, 개수가 많을 수록 예측 성향이 높아짐. 하지만, 수행시간이 오래 걸림. cf.GBM의 n_estimators와 같은 값.
-min_child_weight(default = 1):트리에서 추가적으로 가지를 나눌지 결정하기 위해 필요한 데이터들의 weiht 총합. -> 값이 클수록 분할을 자제하며, 과적합을 조절하기 위해 사용.
-gamma(default=0, alias: min_split_loss):트리의 리프 노드를 추가적으로 나눌지를 결정할 최소 손실 감소 값. ->해당 값보다 큰손실이 감소된 경우, 리프 노드를 분리. 값이 클수록 과적합 감소에 효과적.
-max_depth(default = 6):트리 기반 알고리즘의 max_depth와 같음. ->0을 지정하면 깊이에 제한이 없음. 값이 커지면, 과적합의 가능성도 높아짐.
-sub_sample(default = 1): 트리가 커져서 과적합되는 것을 제어하기 위해 데이터를 샘플링하는 비율 지정 cf. GBM의 subsample과 같은 값. 사이키럿 래퍼 클래스 이용 시, subsample와 같은 값
-colsample_bytree(default=1) ->트리 생성에 필요한 피처를 임의로 샘플링 매우 많은 피처가 있을 경우에는 과적합 조정할 때 사용 GBM의 max_features와 유사
-lambda(default=1, ->reg_lambda) ->L2 regularization 적용 값 피처가 많은 경우 적용을 검토, 값이 클수록 과적합 감소
-alpha(default=0, ->reg_alpha) ->L1 regularization 적용 값 피처가 많은 경우 적용을 검토, 값이 클수록 과적합 감소
*XGBClassifier은 기존의 하이퍼 파라미터와의 호환성을 위해 xgboost 모듈에서 사용하면 네이티브 하이퍼 파리미터를 괄호 안과 같이 변경(이 밖에 eta->learning_rate, sub_sample->subsample로 변경)
-scale_pos_weight(default=1) ->특정 값으로 치운친 데이터 세트의 균형을 유지하기 위한 파라미터
학습 태스크 파라미터
-objective ->최소값을 가져야할 손실함수 주로 다중 분류와 이중 분류에 따라 달라짐
-binary:logistic 이중 분류시 적용
-multi:softmax 다중 분류시 적용 손실함수가 multi:softmax일 때는 래이블 클래수 개수(num_class) 지정
-multi:softprob ->개별 레이블 클래스의 예측 확률 반화 multi:softmax와 유사
-eval_metric ->검증에 사용되는 함수 기본값은 회귀와 분류에 따라 다름(회귀:rmse, 분류:error)
XGBoost보다 학습에 걸리는 시간이 적음. 또한 메모리 사용량도 상대적으로 적음.
XGBoost와의 예측성능은 별다른 차이가 없음.
적은 데이터세트에 대해서는 과적합이 발생할 확률이 큼. (10000건 이하의 데이터)
리프중심분할방식을 사용. (기존의 대부분 트리기반 알고리즘은 트리의 깊이를 효과적으로 줄이기 위한 균형트리분할방식을 사용)
균형트리분할방식 - 최대한 균형 잡힌 트리를 유지하면서 분할하기 때문에 트리의 깊이가 최소화될 수 있음.(오버피팅에 보다 더 강한 구조를 가짐) 대신 시간이 오래걸림.
리프중심분할방식 - 트리의 균형은 무시하고 최대 손실값을 가지는 리프 노드를 지속적으로 분할하면서 트리의 깊이가 깊어지고 비대칭적인 규칙트리 생성.
-> 최대손실값을 가지는 리프노드를 지속적으로 분할하여 생성된 규칙트리는 학습을 반복할수록 결국은 균형트리분할보다 예측 오류 손실을 최소화 가능하다는게 LightGBM 구현 사상임.
from IPython.display import Image
Image("리프중심.png")
<LightGBM 하이퍼 파라미터 >
리프노드가 계속 분할 되면서 트리의 깊이가 깊어짐. -> 트리 특성에 맞게 하이퍼 파라미터 설정이 필요.
주요파라미터
Learning Task 파라미터
num_leaves의 개수를 중심으로 모델의 복잡도를 줄이는 것이 기본 튜닝 방안
learning_rate를 작게 하면서 n_estimators를 크게 하는 것이 부스팅 계열 튜닝에서 가장 기본적 방안
단, n_estimators가 너무 크면 과적합 가능성 있음
from IPython.display import Image
Image("파라미터.jpg")
여기서 파이썬래퍼랑 사이킷런래퍼의 차이에 대해 쉽게 논해보면
파이썬래퍼는 XGBoost로 예를 들면 XGBoost 자체를 말한는거임.
즉, import xgboost as xgb 이런느낌임.
사이킷런래퍼는 XGBoost에서 XGBClassifier과 XGBRegressor로 사용했을때를 말함.
즉, from xgboost import XGBClassifier
그때 사용되는 파라미터의 이름은 차이가 생김. 위에표가 그걸 보여줌.
언더샘플링 - 많은데이터세트를 적은 데이터 세트 수준으로 감소시키는 방식. 이렇게 한 상태에서 학습을 수행하면 과도하게 정상 레이블로 학습/예측하는 부작용을 개선할 수 있지만, 너무 많은 정상 레이블 데이터를 감소시키기 때문에 정상 레이블의 경우 오히려 제대로 된 학습을 수행할 수 없다는 단점이 있음.
오버샘플링 - 이상데이터와 같이 적은 데이터 세트를 증식하여 학습을 위한 충분한 데이터를 확보하는 방법. 동일한 데이터를 단순히 증식하는 방법은 과적합이 되기 때문에 의미가 없으므로 원본데이터의 피처값들을 아주 약간만 변경하여 증식함. 대표적으로 SMOTE방법이 있음.
from IPython.display import Image
Image("오버언더.jpg")
적은 데이터 세트에 있는 개별 데이터들의 K 최근접이웃을 찾아서 이 데이터와 K개 이웃들의 차이를 일정 값으로 만들어서 기존 데이터와 약간 차이가 나는 새로운 데이터들을 생성하는 방식.
from IPython.display import Image
Image("스모트.jpg")
conda install - c conda-forge imbalanced-learn
개별적인 여러 알고리즘을 서로 결합하여 예측결과를 도출한다는 점에서 배깅과 부스팅과 공통점이 있음.
그러나 가장 큰 차이는 개별 알고리즘을 예측한 데이터를 기반으로 다시 예측을 수행한다는 것임.
스태킹모델은 두가지 종류의 모델이 필요함. 첫번째는 개별적인 기반 모델이고, 두 번째 이 개별기반 모델의 예측 데이터를 학습데이터로 만들어서 학습하는 최종 메타 모델임.
from google.colab import files
uploaded = files.upload() # 파일 업로드 기능 실행
for fn in uploaded.keys(): # 업로드된 파일 정보 출력
print('User uploaded file "{name}" with length {length} bytes'.format(
name=fn, length=len(uploaded[fn])))
from IPython.display import Image
Image("스태킹1.jpg")
from IPython.display import Image
Image("스태킹2.jpg")
과적합을 개선하기 위해 최종 메타 모델을 위한 데이터 세트를 만들 때 교차검증기반으로 예측된 결과 데이터 세트를 이용함.
[스텝 1] 각 모델별로 원본 학습/테스트 데이터를 예측한 결과값을 기반으로 메타모델을 위한 학습용/테스트용 데이터를 생성
[스텝2] 스텝 1에서 개별 모델들이 생성한 학습용 데이터를 모두 스태킹 형태로 합쳐서 메타모델이 학습할 최종 학습용 데이터 세트를 생성. 마찬가지로 각 모델들이 생성한 테스트용 데이터를 모두 스태킹 형태로 합쳐서 메타모델이 예측할 최종 테스트 데이터 세트를 생성. 메타모델은 최종적으로 생성된 학습 데이터 세트와 원본 학습 데이터의 레이블 데이터 기반으로 학습한 뒤, 최종적으로 생성된 테스트 데이터 세트를 예측하고, 원본 테스트 레이블 데이터를 기반으로 평가함.
from IPython.display import Image
Image("cv스태킹.jpg")